package com.happysunrise.nru.services.imp;

import org.slf4j.Logger;

import java.util.List;
import java.util.Set;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.happysunrise.nru.managers.ICompetitionManager;
import com.happysunrise.nru.models.Competition;
import com.happysunrise.nru.models.Result;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import com.happysunrise.nru.services.ICompetitionService;


/**
 * CompetitionService的实现.
 * <p>
 * Created by liukaixin on 16/7/16.
 */
@Service
public class CompetitionService implements ICompetitionService {

    private static final Logger LOGGER = LoggerFactory
            .getLogger(CompetitionService.class);

    @Autowired
    ICompetitionManager competitionManager;

    /**
     * 添加竞赛.
     *
     * @param competition 竞赛实体
     * @return 结果集
     */
    @Override
    //TODO(liukx) 2016.07.31 修改为用户友好的提示
    public Result<Integer> addCompetition(Competition competition) {
        Result<Integer> result = new Result<>();
        result.setCode(Result.SUCCESS);
        result.setMessage("竞赛发布成功,等待审核");
        try {
            Integer code = competitionManager.addCompetition(competition);
            if (code != 1) {
                result.setCode(Result.FAILED);
                result.setMessage("发布竞赛失败,请检查网络连接或联系客服");
                LOGGER.error("添加竞赛到数据库失败");
                return result;
            }
        } catch (DuplicateKeyException e) {
            LOGGER.error("竞赛名重复异常:", e);
            result.setCode(Result.FAILED);
            result.setMessage("已有相同竞赛名的比赛,请检查竞赛名称");
            return result;
        } catch (RuntimeException e) {
            LOGGER.error("添加竞赛异常:", e);
            result.setCode(Result.FAILED);
            result.setMessage("发布竞赛失败,请检查网络连接或联系客服");
            return result;
        }
        return result;
    }

    /**
     * 获取发布的竞赛.
     *
     * @param page 页码
     * @param rows 每页条数
     * @return 带有竞赛列表的结果集
     */
    @Override
    public Result<List<Competition>> getReleasedCompetitionsBy(Integer page, Integer rows) {
        Result<List<Competition>> result = new Result<>();
        result.setCode(Result.SUCCESS);
        try {
            List<Competition> competitions = competitionManager
                    .getReleasedCompetitionsBy(page, rows);
            result.setBean(competitions);
        } catch (RuntimeException e) {
            LOGGER.error("查询发布状态的竞赛异常:", e);
            result.setCode(Result.FAILED);
            result.setMessage("获取竞赛失败,请检查网络连接或联系客服");
        }
        return result;
    }

    /**
     * 根据页码和条数以及类型获得竞赛.
     *
     * @param page 页码
     * @param rows 每页显示条数
     * @param type 类型
     * @return 带有竞赛列表的结果即
     */
    @Override
    public Result<List<Competition>> getReleasedCompetitionByType(
            Integer page, Integer rows, String type) {
        Result<List<Competition>> result = new Result<>();
        result.setCode(Result.SUCCESS);
        List<Competition> competitions = competitionManager
                .getReleasedCompetitionsByType(page, rows, type);
        result.setBean(competitions);
        return result;
    }

    /**
     * 根据名称模糊查找竞赛列表.
     *
     * @param page 页码
     * @param rows 每页条数
     * @param name 竞赛名称（模糊）
     * @return 竞赛列表集合
     */
    @Override
    public Result<Set<Competition>> getReleasedCompetitionsByFuzzyName(
            Integer page, Integer rows, String name) {
        Result<Set<Competition>> result = new Result<>();

        Set<Competition> competitions = competitionManager
                .getReleasedCompetitionsByFuzzyName(page, rows, name);
        result.setCode(Result.SUCCESS);
        result.setBean(competitions);
        return result;
    }

    /**
     * 根据竞赛id获取竞赛详情.
     *
     * @param id 竞赛id
     * @return 带竞赛实体的结果集
     */
    @Override
    public Result<Competition> getCompetitionDescById(Integer id) {
        Result<Competition> result = new Result<>();
        Competition competition = competitionManager
                .getCompetitionDescById(id);
        if (competition == null) {
            result.setCode(Result.FAILED);
            result.setMessage("竞赛不存在");
            return result;
        }
        result.setCode(Result.SUCCESS);
        result.setBean(competition);
        return result;
    }

    /**
     * 根据竞赛名称精确匹配查询竞赛详情.
     *
     * @param name 精确竞赛名称
     * @return 竞赛结果集
     */
    @Override
    public Result<Competition> getCompetitionDescByExactName(String name) {
        Result<Competition> result = new Result<>();
        Competition competition = competitionManager
                .getCompetitionByExactName(name);
        if (competition == null) {
            result.setCode(Result.FAILED);
            result.setMessage("竞赛不存在");
            return result;
        }
        result.setCode(Result.SUCCESS);
        result.setBean(competition);
        return result;
    }

    /**
     * 更改竞赛.
     *
     * @param competition 竞赛
     * @return 结果
     */
    @Override
    public Result updateCompetition(Competition competition) {
        Result result = new Result();
        if (competitionManager.updateCompetition(competition) == 1) {
            result.setCode(Result.SUCCESS);
            result.setMessage("更改竞赛成功！");
        } else {
            result.setCode(Result.FAILED);
            result.setMessage("更改失败，请重试");
        }
        return result;
    }

    /**
     * 根据页码和条数以及用户Id获得竞赛.
     *
     * @param page 页码
     * @param rows 每页显示条数
     * @param userId 用户Id
     * @return 带有竞赛列表的结果集
     */
    @Override
    public Result<List<Competition>> getCompetitionsByUserId(Integer page,
                                                             Integer rows,
                                                             Integer userId) {
        Result<List<Competition>> result = new Result<>();
        result.setCode(Result.SUCCESS);
        List<Competition> myCompetitions = competitionManager
                .getCompetitionsByUserId(page, rows, userId);
        result.setBean(myCompetitions);
        return result;
    }
}
